from datetime import datetime
import os
from typing import List

from script_executor.Domain import Domain, InputItem
import pandas as pd


class ExcelColumnExtractor(Domain):
    """继承自Domain类，必须实现所有抽象方法"""
    def __init__(self):
        self.directory_path = None
        self.excel_path = None

    def get_input_items(self) -> List[InputItem]:
        """定义需要的输入项：Excel文件路径和工作表选择"""
        return [
            InputItem(
                label="扫描文件路径",
                input_name="directory_path",
                input_type="folder",
                default_value="",
                placeholder_text="请选择文件路径，程序将扫描这个路径所有文件，并生成文件名清单excel",
                options=[]
            ),InputItem(
                label="结果文件路径",
                input_name="excel_path",
                input_type="folder",
                default_value="",
                placeholder_text="请选择结果excel文件路径，程序将把结果写入到这个路径下",
                options=[]
            )
        ]

    def execute(self) -> str:
        files_info = self.get_file_info(self.directory_path)
        if files_info:
            result_info = self.save_to_excel(files_info)
            return f"共发现 {len(files_info)} 个文件， {result_info}"
        else:
            return "未发现任何文件"

    def save_to_excel(self, file_info_list, output_file="文件信息汇总.xlsx"):
        if not file_info_list:
            return "没有获取到任何文件信息，无法生成Excel文件"

        # 创建DataFrame
        df = pd.DataFrame(file_info_list)

        # 保存到Excel
        try:
            target_path = os.path.join(self.excel_path, output_file)
            df.to_excel(target_path, index=False, engine='openpyxl')
            return f"文件信息已成功保存到 {target_path}"
        except Exception as e:
            return f"保存Excel文件时出错: {str(e)}"

    def get_file_info(self, root_path):
        file_info_list = []

        # 递归遍历目录
        for root, dirs, files in os.walk(root_path):
            for file in files:
                try:
                    # 获取文件完整路径
                    file_path = os.path.join(root, file)

                    # 获取文件基本信息
                    stat_info = os.stat(file_path)

                    # 转换时间戳为可读时间格式
                    create_time = datetime.fromtimestamp(stat_info.st_ctime).strftime('%Y-%m-%d %H:%M:%S')
                    modify_time = datetime.fromtimestamp(stat_info.st_mtime).strftime('%Y-%m-%d %H:%M:%S')

                    # 文件大小（字节）
                    file_size = stat_info.st_size

                    # 将信息添加到列表
                    file_info = {
                        '文件名': file,
                        '文件类型': self.get_file_extension(file),
                        '文件路径': file_path,
                        '创建时间': create_time,
                        '最后修改时间': modify_time,
                        '文件大小': self.convert_bytes(file_size),
                        '文件大小(字节)': file_size
                    }
                    file_info_list.append(file_info)

                except Exception as e:
                    print(f"处理文件 {os.path.join(root, file)} 时出错: {str(e)}")

        return file_info_list

    def convert_bytes(self, size_in_bytes):
        """
        将字节大小转换为最适合的单位（KB或MB）

        参数:
            size_in_bytes: 以字节为单位的文件大小

        返回:
            转换后的大小和单位的元组 (大小数值, 单位字符串)
        """
        # 定义单位转换关系
        KB = 1024
        MB = KB * 1024

        # 根据大小选择合适的单位
        if size_in_bytes >= MB:
            # 转换为MB
            return f'{round(size_in_bytes / MB, 2)} MB'
        elif size_in_bytes >= KB:
            # 转换为KB
            return f'{round(size_in_bytes / KB, 2)} KB'
        else:
            # 保持字节单位
            return f'{size_in_bytes} B'

    def get_file_extension(self, filename):
        # splitext会将文件名分割为(文件名, 后缀名)的元组
        # 例如 "file.txt" 会分割为 ("file", ".txt")
        _, ext = os.path.splitext(filename)
        return ext  # 返回带点的后缀名，如".txt"